package com.init.iblog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.init.iblog.constants.SystemConstants;
import com.init.iblog.domain.ResponseResult;
import com.init.iblog.domain.entity.Menu;
import com.init.iblog.domain.vo.MenuVo;
import com.init.iblog.domain.vo.RoleMenuVo;
import com.init.iblog.enums.AppHttpCodeEnum;
import com.init.iblog.exception.SystemException;
import com.init.iblog.mapper.MenuMapper;
import com.init.iblog.service.MenuService;
import com.init.iblog.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2023-03-04 23:10:06
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired(required = false)
    private MenuMapper menuMapper;

    /**
     * 根据用户id查询权限关键字
     * @param id
     * @return
     */
    @Override
    public List<String> selectPermsByUserId(Long id) {
        //如果是管理员，返回所有的权限
        if(SecurityUtils.isAdmin()){
            LambdaQueryWrapper<Menu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            //菜单集合在C或F中
            lambdaQueryWrapper.in(Menu::getMenuType, SystemConstants.MENU,SystemConstants.BUTTON);
            lambdaQueryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);
            List<Menu> menus = list(lambdaQueryWrapper);
            List<String> perms = menus.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            return perms;
        }
        //否则返回所具有的权限

        return getBaseMapper().selectPermsByUserId(id);
    }

    @Override
    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是管理员
        if(SecurityUtils.isAdmin()){
            //如果是，则返回所有符号要求的Menu
            menus = menuMapper.selectAllRouterMenu();

        }else{
            //如果不是，则返回当前用户角色所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }

        //构建tree
        //先找出第一层的菜单，然后去找它们足子菜单设置到children属性中
        List<Menu> menuTree = builderMenuTree(menus,0L);

        return menuTree;
    }

    /**
     * 查询菜单列表
     * @param status
     * @param menuName
     * @return
     */
    @Override
    public ResponseResult getMenuList(String status, String menuName) {

        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.hasText(status)){
            queryWrapper.eq(Menu::getStatus,status);
        }
        if(StringUtils.hasText(menuName)){
            queryWrapper.eq(Menu::getMenuName,menuName);
        }
        List<Menu> menuList = list(queryWrapper);
        return ResponseResult.okResult(menuList);
    }

    /**
     * 新增菜单
     * @param menu
     * @return
     */
    @Override
    public ResponseResult addMenu(Menu menu) {
        save(menu);
        return ResponseResult.okResult();
    }

    /**
     * 根据id查询菜单信息
     * @param id
     * @return
     */
    @Override
    public ResponseResult getMenuInfo(Long id) {
        Menu menu = menuMapper.selectById(id);
        return ResponseResult.okResult(menu);
    }


    /**
     * 修改菜单信息
     * @param menu
     * @return
     */
    @Override
    public ResponseResult editMenu(Menu menu) {
        updateById(menu);
        return ResponseResult.okResult();
    }


    /**
     * 删除菜单
     * 当有子菜单时，不允许删除
     * @param menuId
     * @return
     */
    @Override
    public ResponseResult deleteMenu(Long menuId) {
        //判断该菜单是否有子菜单
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId,menuId);
        System.out.println("===========menuId="+menuId);
        List<Menu> list = list(queryWrapper);
        System.out.println("+++++++++++++++"+list.size());
        if(list.size() > 0 ){
            throw new SystemException(AppHttpCodeEnum.EXIST_CHILDREN_MENU);
        }
        //没有子菜单
        removeById(menuId);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult treeselect() {
        List<Menu> menus = null;
        menus = menuMapper.selectAllRouterMenu();
        List<RoleMenuVo> roleMenuVos = new ArrayList<>();
        //RoleMenuVo roleMenuVo = new RoleMenuVo();
        for(Menu menu:menus){
            RoleMenuVo roleMenuVo = new RoleMenuVo();
            System.out.println("-----" + menu.toString());

            roleMenuVo.setId(menu.getId());
            roleMenuVo.setLabel(menu.getMenuName());
            roleMenuVo.setParentId(menu.getParentId());
            roleMenuVos.add(roleMenuVo);
        }
        List<RoleMenuVo> roleMenuTree = builderRoleMenuVoTree(roleMenuVos, 0L);
        System.out.println("+++++++++++++++++++++" + roleMenuTree.toString());

        return ResponseResult.okResult(roleMenuTree);
    }


    /**
     * TODO  未实现
     * @param id
     * @return
     */
    @Override
    public ResponseResult roleMenuTreeselect(Long id) {


        return null;

    }



    private List<Menu> builderMenuTree(List<Menu> menus,Long parentId) {
        List<Menu> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren(menu,menus)))
                .collect(Collectors.toList());

        //

        return menuTree;
    }

    /**
     * 获取传入参数的子Menu
     * @param menu
     * @param menus
     * @return
     */
    private List<Menu> getChildren(Menu menu,List<Menu> menus) {
        List<Menu> childrenList = menus.stream()
                .filter(menu1 -> menu1.getParentId().equals(menu.getId()))
                .map(menu1 -> menu1.setChildren(getChildren(menu1,menus)))
                .collect(Collectors.toList());
        return childrenList;
    }


    private List<RoleMenuVo> builderRoleMenuVoTree(List<RoleMenuVo> menus,Long parentId) {
        List<RoleMenuVo> menuTree = menus.stream()
                .filter(roleMenuVo -> roleMenuVo.getParentId().equals(parentId))
                .map(roleMenuVo -> roleMenuVo.setChildren(getChildren(roleMenuVo,menus)))
                .collect(Collectors.toList());

        //

        return menuTree;
    }

    private List<RoleMenuVo> getChildren(RoleMenuVo roleMenuVo,List<RoleMenuVo> menus) {
        List<RoleMenuVo> childrenList = menus.stream()
                .filter(roleMenuVo1 -> roleMenuVo1.getParentId().equals(roleMenuVo.getId()))
                .map(roleMenuVo1 -> roleMenuVo1.setChildren(getChildren(roleMenuVo1,menus)))
                .collect(Collectors.toList());
        return childrenList;
    }


}
